﻿using System.Collections.Generic;
using UnityEngine;

namespace BoyInABox
{
    #region Body Bones

    [System.Serializable]
    public class HS_HumanoidBone
    {
        public HS_HumanoidBone_Body body;
        public HS_HumanoidBone_Arm leftArm;
        public HS_HumanoidBone_Arm rightArm;
        public HS_HumanoidBone_Leg leftLeg;
        public HS_HumanoidBone_Leg rightLeg;
        public HS_HumanoidBone_Head head;

        public void SetHSHumanoidBones(Animator animator)
        {
            {
                body.hips = animator.GetBoneTransform(HumanBodyBones.Hips);
                body.spine = animator.GetBoneTransform(HumanBodyBones.Spine);
                body.chest = animator.GetBoneTransform(HumanBodyBones.Chest);
                body.upperChest = animator.GetBoneTransform(HumanBodyBones.UpperChest);
            }

            {
                leftArm.shoulder = animator.GetBoneTransform(HumanBodyBones.LeftShoulder);
                leftArm.upperArm = animator.GetBoneTransform(HumanBodyBones.LeftUpperArm);
                leftArm.lowerArm = animator.GetBoneTransform(HumanBodyBones.LeftLowerArm);

                leftArm.hand.thumb.proximal = animator.GetBoneTransform(HumanBodyBones.LeftThumbProximal);
                leftArm.hand.thumb.intermediate = animator.GetBoneTransform(HumanBodyBones.LeftThumbIntermediate);
                leftArm.hand.thumb.distal = animator.GetBoneTransform(HumanBodyBones.LeftThumbDistal);

                leftArm.hand.index.proximal = animator.GetBoneTransform(HumanBodyBones.LeftIndexProximal);
                leftArm.hand.index.intermediate = animator.GetBoneTransform(HumanBodyBones.LeftIndexIntermediate);
                leftArm.hand.index.distal = animator.GetBoneTransform(HumanBodyBones.LeftIndexDistal);

                leftArm.hand.middle.proximal = animator.GetBoneTransform(HumanBodyBones.LeftMiddleProximal);
                leftArm.hand.middle.intermediate = animator.GetBoneTransform(HumanBodyBones.LeftMiddleIntermediate);
                leftArm.hand.middle.distal = animator.GetBoneTransform(HumanBodyBones.LeftMiddleDistal);

                leftArm.hand.ring.proximal = animator.GetBoneTransform(HumanBodyBones.LeftRingProximal);
                leftArm.hand.ring.intermediate = animator.GetBoneTransform(HumanBodyBones.LeftRingIntermediate);
                leftArm.hand.ring.distal = animator.GetBoneTransform(HumanBodyBones.LeftRingDistal);

                leftArm.hand.little.proximal = animator.GetBoneTransform(HumanBodyBones.LeftLittleProximal);
                leftArm.hand.little.intermediate = animator.GetBoneTransform(HumanBodyBones.LeftLittleIntermediate);
                leftArm.hand.little.distal = animator.GetBoneTransform(HumanBodyBones.LeftLittleDistal);
            }

            {
                rightArm.shoulder = animator.GetBoneTransform(HumanBodyBones.RightShoulder);
                rightArm.upperArm = animator.GetBoneTransform(HumanBodyBones.RightUpperArm);
                rightArm.lowerArm = animator.GetBoneTransform(HumanBodyBones.RightLowerArm);

                rightArm.hand.thumb.proximal = animator.GetBoneTransform(HumanBodyBones.RightThumbProximal);
                rightArm.hand.thumb.intermediate = animator.GetBoneTransform(HumanBodyBones.RightThumbIntermediate);
                rightArm.hand.thumb.distal = animator.GetBoneTransform(HumanBodyBones.RightThumbDistal);

                rightArm.hand.index.proximal = animator.GetBoneTransform(HumanBodyBones.RightIndexProximal);
                rightArm.hand.index.intermediate = animator.GetBoneTransform(HumanBodyBones.RightIndexIntermediate);
                rightArm.hand.index.distal = animator.GetBoneTransform(HumanBodyBones.RightIndexDistal);

                rightArm.hand.middle.proximal = animator.GetBoneTransform(HumanBodyBones.RightMiddleProximal);
                rightArm.hand.middle.intermediate = animator.GetBoneTransform(HumanBodyBones.RightMiddleIntermediate);
                rightArm.hand.middle.distal = animator.GetBoneTransform(HumanBodyBones.RightMiddleDistal);

                rightArm.hand.ring.proximal = animator.GetBoneTransform(HumanBodyBones.RightRingProximal);
                rightArm.hand.ring.intermediate = animator.GetBoneTransform(HumanBodyBones.RightRingIntermediate);
                rightArm.hand.ring.distal = animator.GetBoneTransform(HumanBodyBones.RightRingDistal);

                rightArm.hand.little.proximal = animator.GetBoneTransform(HumanBodyBones.RightLittleProximal);
                rightArm.hand.little.intermediate = animator.GetBoneTransform(HumanBodyBones.RightLittleIntermediate);
                rightArm.hand.little.distal = animator.GetBoneTransform(HumanBodyBones.RightLittleDistal);
            }

            {
                leftLeg.upperLeg = animator.GetBoneTransform(HumanBodyBones.LeftUpperLeg);
                leftLeg.lowerLeg = animator.GetBoneTransform(HumanBodyBones.LeftLowerLeg);
                leftLeg.foot = animator.GetBoneTransform(HumanBodyBones.LeftFoot);
                leftLeg.toes = animator.GetBoneTransform(HumanBodyBones.LeftToes);
            }

            {
                rightLeg.upperLeg = animator.GetBoneTransform(HumanBodyBones.RightUpperLeg);
                rightLeg.lowerLeg = animator.GetBoneTransform(HumanBodyBones.RightLowerLeg);
                rightLeg.foot = animator.GetBoneTransform(HumanBodyBones.RightFoot);
                rightLeg.toes = animator.GetBoneTransform(HumanBodyBones.RightToes);
            }

            {
                head.neck = animator.GetBoneTransform(HumanBodyBones.Neck);
                head.head = animator.GetBoneTransform(HumanBodyBones.Head);
                head.leftEye = animator.GetBoneTransform(HumanBodyBones.LeftEye);
                head.rightEye = animator.GetBoneTransform(HumanBodyBones.RightEye);
            }
        }
    }

    [System.Serializable]
    public class HS_HumanoidBone_Body
    {
        public Transform hips;
        public Transform spine;
        public Transform chest;
        public Transform upperChest;
    }

    [System.Serializable]
    public class HS_HumanoidBone_Leg
    {
        public Transform upperLeg;
        public Transform lowerLeg;
        public Transform foot;
        public Transform toes;
    }

    [System.Serializable]
    public class HS_HumanoidBone_Arm
    {
        public Transform shoulder;
        public Transform upperArm;
        public Transform lowerArm;
        public HS_HumanoidBone_Hand hand;
    }

    [System.Serializable]
    public class HS_HumanoidBone_Hand
    {
        public HS_HumanoidBone_Finger thumb;
        public HS_HumanoidBone_Finger index;
        public HS_HumanoidBone_Finger middle;
        public HS_HumanoidBone_Finger ring;
        public HS_HumanoidBone_Finger little;
    }

    [System.Serializable]
    public class HS_HumanoidBone_Finger
    {
        public Transform proximal;
        public Transform intermediate;
        public Transform distal;
    }

    [System.Serializable]
    public class HS_HumanoidBone_Head
    {
        public Transform neck;
        public Transform head;
        public Transform leftEye;
        public Transform rightEye;
    }

    #endregion Body Bones

    #region Combine & Deform Bone

    public enum HS_TransformVector
    {
        X, Y, Z
    }

    [System.Serializable]
    public class CombineBone
    {
        [Tooltip("旋转骨名称")]
        public string boneName;

        [Tooltip("主要骨")]
        public Transform mainBone;

        [Tooltip("跟随骨")]
        public List<CombineFollowBone> followBones = new List<CombineFollowBone>();
    }

    [System.Serializable]
    public class CombineFollowBone
    {
        [Tooltip("跟随骨")]
        public Transform followBone;

        [Tooltip("跟随骨旋转权重")]
        public float weight;
    }

    [System.Serializable]
    public class DeformBone
    {
        [Tooltip("变形骨名称")]
        public string boneName;

        [Tooltip("主要骨")]
        public Transform mainBone;

        [Tooltip("跟随骨")]
        public List<DeformFollowBone> followBones = new List<DeformFollowBone>();
    }

    [System.Serializable]
    public class DeformFollowBone
    {
        [Tooltip("跟随骨")]
        public Transform followBone;

        [Tooltip("主要骨角度设置")]
        public HS_TransformVector mainAngleDir;

        [Tooltip("主要骨最小角度")]
        public float minDeformAngle;

        [Tooltip("主要骨最大角度")]
        public float maxDeformAngle;

        [Tooltip("跟随骨角度设置")]
        public HS_TransformVector followAngleDir;

        [Tooltip("跟随骨最小变换系数ֵ")]
        public float minDeformScale;

        [Tooltip("跟随骨最大变换系数ֵ")]
        public float maxDeformScale;
    }

    #endregion Combine & Deform Bone

    #region IO

    [System.Serializable]
    public class CombineBoneDatas
    {
        public List<CombineBoneData> combineBoneDatas = new List<CombineBoneData>();
    }

    [System.Serializable]
    public class CombineBoneData
    {
        public string boneName;
        public string mainBoneName;
        public List<CombineFollowBoneData> followBoneDatas = new List<CombineFollowBoneData>();
    }

    [System.Serializable]
    public class CombineFollowBoneData
    {
        public string followBoneName;
        public float weight;
    }

    [System.Serializable]
    public class DeformBoneDatas
    {
        public List<DeformBoneData> deformBoneDatas = new List<DeformBoneData>();
    }

    [System.Serializable]
    public class DeformBoneData
    {
        public string boneName;
        public string mainBoneName;
        public List<DeformFollowBoneData> followBoneDatas = new List<DeformFollowBoneData>();
    }

    [System.Serializable]
    public class DeformFollowBoneData
    {
        public string followBoneName;
        public HS_TransformVector mainAngleDir;
        public float minDeformAngle;
        public float maxDeformAngle;
        public HS_TransformVector followAngleDir;
        public float minDeformScale;
        public float maxDeformScale;
    }

    #endregion IO

    #region Extra Bone Data

    public class ExtraEmptyBones
    {
        public List<string> boneNames = new List<string>
        {
            "ct_clothesBot",
            "ct_clothesTop",
            "ct_gloves",
            "ct_inner_t",
            "ct_inner_b",
            "ct_panst",
            "ct_shoes",
            "ct_socks",
            "p_cf_body_00",
            "p_cf_body_silhouette",

            "f_t_arm_L(work)",
            "f_t_arm_R(work)",
            "f_t_elbo_L(work)",
            "f_t_elbo_R(work)",
            "f_t_hips(work)",
            "f_t_knee_L(work)",
            "f_t_knee_R(work)",
            "f_t_leg_L(work)",
            "f_t_leg_R(work)",
            "f_t_shoulder_L(work)",
            "f_t_shoulder_R(work)",
            "f_t_thigh_L(work)",
            "f_t_thigh_R(work)",

            "cf_t_root",
            "cf_N_k"
        };
    }

    public class ExtraMuneBones
    {
        public List<string> leftBoneNames = new List<string>
        {
            "k_f_mune00L_00",
            "k_f_mune00L_01",
            "k_f_mune00L_02",
            "k_f_mune00L_03",

            "k_f_mune01L_00",
            "k_f_mune01L_01",
            "k_f_mune01L_02",
            "k_f_mune01L_03",

            "k_f_mune02L_00",
            "k_f_mune02L_01",
            "k_f_mune02L_02",
            "k_f_mune02L_03",

            "k_f_mune03L_00",
            "k_f_mune03L_01",
            "k_f_mune03L_02",
            "k_f_mune03L_03",

            "k_f_mune04L_00",
            "k_f_mune04L_01",
            "k_f_mune04L_02",
            "k_f_mune04L_03",

            "k_f_munenipL_00",
            "k_f_munenipL_01",
            "k_f_munenipL_02",
            "k_f_munenipL_03"
        };

        public List<string> rightBoneNames = new List<string>
        {
            "k_f_mune00R_00",
            "k_f_mune00R_01",
            "k_f_mune00R_02",
            "k_f_mune00R_03",

            "k_f_mune01R_00",
            "k_f_mune01R_01",
            "k_f_mune01R_02",
            "k_f_mune01R_03",

            "k_f_mune02R_00",
            "k_f_mune02R_01",
            "k_f_mune02R_02",
            "k_f_mune02R_03",

            "k_f_mune03R_00",
            "k_f_mune03R_01",
            "k_f_mune03R_02",
            "k_f_mune03R_03",

            "k_f_mune04R_00",
            "k_f_mune04R_01",
            "k_f_mune04R_02",
            "k_f_mune04R_03",

            "k_f_munenipR_00",
            "k_f_munenipR_01",
            "k_f_munenipR_02",
            "k_f_munenipR_03"
        };
    }

    public class ExtraVaginaBones
    {
        public List<string> leftBoneNames = new List<string>
        {
            "cf_J_Vagina_s_F_L_end",
            "cf_J_Vagina_s_M_F_L_end",
            "cf_J_Vagina_s_M_L_end",
            "cf_J_Vagina_s_M_B_L_end",
            "cf_J_Vagina_s_B_L_end"
        };

        public List<string> rightBoneNames = new List<string>
        {
            "cf_J_Vagina_s_F_R_end",
            "cf_J_Vagina_s_M_F_R_end",
            "cf_J_Vagina_s_M_R_end",
            "cf_J_Vagina_s_M_B_R_end",
            "cf_J_Vagina_s_B_R_end"
        };
    }

    #endregion Extra Bone Data
}